import {
  BaseEdge,
  ExtensionCategory,
  Graph,
  GraphData,
  IKeyboardEvent,
  IPointerEvent,
  NodeData,
  register,
  treeToGraphData,
} from "@antv/g6";
import { useCallback, useEffect, useRef } from "react";
import { treeData } from "./qfg5data";

interface INodeData extends NodeData {
  data?: { label: string; width: number; height: number };
}

class PolylineEdge extends BaseEdge {
  getKeyPath(attributes) {
    const [sourcePoint, targetPoint] = this.getEndpoints(attributes);

    return [
      ["M", sourcePoint[0], sourcePoint[1]],
      ["L", sourcePoint[0] + 40, sourcePoint[1]],
      ["L", targetPoint[0] - 40, targetPoint[1]],
      // ["L", targetPoint[0] / 3 + (1 / 3) * sourcePoint[0], sourcePoint[1]],
      // ["L", targetPoint[0] / 3 + (1 / 3) * sourcePoint[0], targetPoint[1]],
      ["L", targetPoint[0], targetPoint[1]],
    ] as ReturnType<InstanceType<typeof BaseEdge>["getKeyPath"]>;
  }
}

register(ExtensionCategory.EDGE, "custom-polyline", PolylineEdge);

const getNodeSide = (graph, datum) => {
  const parentData = graph.getParentData(datum.id, "tree");
  if (!parentData) return "center";
  return datum.style.x > parentData.style.x ? "right" : "left";
};

const ChartDemo1 = () => {
  const ref = useRef<HTMLDivElement & { graph?: Graph }>(null);

  const getData = useCallback(() => {
    // return fetch("https://assets.antv.antgroup.com/g6/combo.json")
    // .then((res) => res.json())
    // .then((data) => {

    const graph = ref.current.graph;

    let data = { id: "root", label: "跟", children: treeData };
    let gd = {
      nodes: [
        // { id: "root", label: "根节点" } as any
        // ...new Array(10).fill(1).map((v, i) => ({ id: "m" + i, label: "层级1：" + i })),
      ],
      edges: [
        // ...new Array(9).fill(1).map((v, i) => ({ source: `m${i}`, target: `m${i + 1}`, type: "polyline" })),

        { source: "l1t11", target: "l2t1" },
        { source: "l1t12", target: "l2t1" },
        { source: "l1t13", target: "l2t1" },
        { source: "l1t14", target: "l2t1" },
        { source: "l1t15", target: "l2t1" },

        { source: "l2t1", target: "t3" },
        { source: "l2t2", target: "ta3" },

        // ===
        { source: "l1t13", target: "l2t1", style: { visibility: "hidden" } },
        { source: "l1t13", target: "l2t2", style: { visibility: "hidden" } },
        { source: "l1t13", target: "l2t3", style: { visibility: "hidden" } },

        { source: "d3511", target: "l4t1", style: { visibility: "hidden" } },
        { source: "d3511", target: "l4t2", style: { visibility: "hidden" } },
        { source: "d3511", target: "l4t3", style: { visibility: "hidden" } },
        { source: "d3511", target: "l4t4", style: { visibility: "hidden" } },

        { source: "l4t18", target: "l5t1", style: { visibility: "hidden" } },
        { source: "l4t18", target: "l5t2", style: { visibility: "hidden" } },
        { source: "l4t18", target: "l5t3", style: { visibility: "hidden" } },
        { source: "l4t18", target: "l5t4", style: { visibility: "hidden" } },
      ],
      combos: [
        { id: "部门预算", type: "rect" },
        { id: "指标下达", type: "rect" },
        { id: "资金支付", type: "rect" },
        { id: "会计核算", type: "rect" },
        { id: "决算", type: "rect" },
      ],
    } as GraphData;
    treeData.map((v) => {
      const d = treeToGraphData(v, {
        getNodeData: (datum, depth) => {
          if (!datum.style) datum.style = {};
          // datum.style.collapsed = depth >= 2;

          const { children = [], ...restDatum } = datum;
          const nd = {
            ...restDatum,
            combo: restDatum.shape,
            children: children.map((child) => child.id),
          } as NodeData;

          if (!datum.children) delete nd.children;
          return nd;
        },
      });
      gd.nodes.push(...d.nodes);
      gd.edges.push(...d.edges);
    });

    graph.setData(gd);
    graph.render();
    // });
  }, []);

  useEffect(() => {
    const graph = new Graph({
      container: ref.current,
      background: "#F2F7FA",
      autoFit: "center",
      node: {
        style: {
          iconText: (d: any) => d.id,
          iconFontSize: 12,
          labelText: (d: any) => d.label,
          labelBackground: false,
          labelPlacement: function (d) {
            return "bottom";
          },
          ports: [{ placement: "right" }, { placement: "left" }],
        },
        palette: {
          type: "group",
          field: (d) => d.shape as string,
          // field: "shape",
        },
        animation: {
          enter: false,
        },
      },
      edge: {
        type: (d) => d.type || "custom-polyline",
        style: {
          endArrow: true,
        },
        animation: {
          enter: false,
        },
      },
      combo: {
        style: {
          labelText: (d) => d.id,
          labelPlacement: "top",
        },
      },
      layout: {
        type: "antv-dagre",
        ranksep: 40,
        nodesep: 15,
        rankdir: "LR",

        // type: "dendrogram",
        // rankdir: "LR",
        // nodeSize: [30, 30],
        // nodesep: 60,
        // ranksep: 40,
        // controlPoints: true,

        // type: "mindmap",
        // direction: "H",
        // getHeight: () => 32,
        // getWidth: () => 32,
        // getVGap: () => 12,
        // getHGap: () => 64,
      },
      behaviors: [
        {
          key: "lasso-select",
          type: "lasso-select",
          mode: "diff",
          trigger: "shift",
          style: {
            fill: "#00f",
            fillOpacity: 0.1,
            stroke: "#0ff",
            lineWidth: 2,
          },
        },
        {
          key: "drag-canvas",
          type: "drag-canvas",
          enable: (ev: IPointerEvent | IKeyboardEvent) => {
            if (ev.shiftKey || (ev as any).targetType !== "canvas") {
              return false;
            }
            return true;
          },
        },
        "collapse-expand",
        "drag-element",
        "zoom-canvas",
      ],
      animation: false,
    });

    ref.current.graph = graph;
    graph.render();

    getData();
  }, []);

  return (
    <>
      <h2>官方：脑图树示例 - 5 财政组织预算</h2>
      <div ref={ref} style={{ width: "100%", minHeight: 600 }}></div>
    </>
  );
};

export default ChartDemo1;
